package com.second.app.superthread;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @Author GYZ
 * @Date 2024/1/22
 * <pre>
 * CyclicBarrier
 *  cyclic 周期循环的意思
 *  barrier 门删 关卡 障碍
 *  CyclicBarrier 不仅具备CountDownLatch的功能，还可以实现屏障等待的功能，也就是阶段性同步
 *  使用的意义：
 *      可以循环的实现线程要一起做任务的目标，而不是像countDownLatch一样，仅仅支持一次线程与同步点的阻塞性
 *  countDownLatch的作用：一个线程或者多个线程，等待另外一个线程或多个线程完成某个事情后才能继续执行。
 *  cyclicBarrier的作用：多个线程之间
 *
 *
 *
 *
 * </pre>
 */

//如果实验中线程个数和parties个数是相同的，如果线程个数大于parties数量时能不能进行分批处理？
// 从运行 结果来看 是可以实现分批进行比赛的效果，也就是每出现2个运动员就开始比赛
class Cyclic01Thread extends Thread {

    private final CyclicBarrier cbRef;

    public Cyclic01Thread(CyclicBarrier cbRef) {
        this.cbRef = cbRef;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " begin=" + System.currentTimeMillis()+" 等待凑齐2个继续运行");
            cbRef.await();
            System.out.println(Thread.currentThread().getName() + " end=" + System.currentTimeMillis()+" 已经凑齐2个继续运行");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
class Test{
    public static void main(String[] args) {
        CyclicBarrier chRef =  new CyclicBarrier(2, () -> System.out.println("全来了"));

        for (int i=0;i<4;i++){
           Cyclic01Thread thread = new Cyclic01Thread(chRef);
            thread.start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
//CyclicBarrier chRef =  new CyclicBarrier(5,new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("全都到了");
//            }
//        }); 的作用是设置最大为5个parties同行者，也就是5个线程都执行cbRef对象的await()方法后 程序才可以继续向下运行，否则这些线程互相等待，一直呈阻塞状态。
class CyclicThread extends Thread {

    private CyclicBarrier cbRef;

    public CyclicThread(CyclicBarrier cbRef) {
        this.cbRef = cbRef;
    }

    @Override
    public void run() {
        try {
            Thread.sleep((int) (Math.random() * 1000));
            System.out.println(Thread.currentThread().getName() + " 到了！" + System.currentTimeMillis());
            cbRef.await();
            System.out.println(Thread.currentThread().getName() + " 去旅游！" + System.currentTimeMillis());
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

public class CyclicBarrierDemo {
    public static void main(String[] args) {
      CyclicBarrier chRef =  new CyclicBarrier(5, () -> System.out.println("全都到了"));

        CyclicThread[] cyclicThreads = new CyclicThread[5];

        for (int i = 0; i < cyclicThreads.length; i++) {
            cyclicThreads[i] = new CyclicThread(chRef);
        }

        for (int i=0;i<cyclicThreads.length;i++){
            cyclicThreads[i].start();
        }
    }
}